perm filename MONPLY.SAI[DKH,LCS] blob sn#003063 filedate 1975-01-08 generic text, type T, neo UTF8
COMMENT ⊗   VALID 00012 PAGES 
RECORD PAGE   DESCRIPTION
 00001 00001
 00002 00002	BEGIN "MONPLY"
 00004 00003	α THE NAMES AND ATTRIBUTIONS OF THE PROPERTIES
 00007 00004	α THE CARDS
 00011 00005	α MISC. DISPLAY ROUTINES
 00013 00006	α ROLL DICE
 00015 00007	α OWNERSHIP ROUTINES
 00016 00008	α THE PRICING
 00019 00009	α DISPLAY STATE
 00022 00010	α PLAYER HAS TO SPEND MONEY FOR SOMETHING
 00025 00011	α SETUP THE BOARD
 00027 00012	α ACTUAL PLAYING
 00040 ENDMK
⊗;
BEGIN "MONPLY"

COMMENT 	WITH APOLOGIES TO MILTON-BRADLY;

	REQUIRE "ABBREV[SYS,BGB]" SOURCE_FILE;
	REQUIRE "DPYIII[SYS,BGB]" SOURCE_FILE;
	REQUIRE "RANDOM[SYS,BGB]" LOAD_MODULE;
	INTEGER ARRAY DPYBUF[1:2000];
	EXTERNAL PROCEDURE TYPLOC(INTEGER Y1,Y2);
	EXTERNAL REAL PROCEDURE RANDOM;

DEFINE NO_OP="⊂ ⊃";

α PIECE OF GLASS USAGE;
  DEFINE BOARD		=   1;
  DEFINE CHANCE		=   2;
  DEFINE COMCHEST	=   3;
  DEFINE DICE		=   4;
  DEFINE PLAYER		=   5;
  DEFINE ACCOUNT	=   6;
  DEFINE MSGPOG		=   7;
  DEFINE OWNERS		=   8;
  DEFINE MSG2POG	=   9;

  BOOLEAN DOUBLES;
  INTEGER PLAYERS,DOUBLECOUNT,ROLL;
  INTEGER I,J,K,XINC,YINC,XPOS,YPOS,TEMP;
  INTEGER ARRAY MONEY[1:5],INJAIL[1:5],POS[1:5];
  STRING TMPSTR;
  STRING ARRAY INITIALS[1:5];
α THE NAMES AND ATTRIBUTIONS OF THE PROPERTIES;

PRELOAD_WITH
  "GO",
  "MEDITER-RANEAN",
  "COMMUNITY -CHEST",
  "BALTIC",
  "INCOME TAX",
  "READING -R.R.",
  "ORIENTAL",
  "CHANCE -?",
  "VERMONT",
  "CONNETICUT",

  "JUST VISIT-ING JAIL",
  "ST. CHARLES -PLACE",
  "ELECTRIC -CO.",
  "VIRGINIA",
  "STATES",
  "PENNSYL-VANIA R.R.",
  "ST. JAMES",
  "TENNESSEE",
  "COMMUNITY -CHEST",
  "NEW YORK",

  "FREE -PARKING",
  "KENTUCKY",
  "CHANCE -?",
  "INDIANA",
  "ILLINOIS",
  "B. & O. -R.R.",
  "ATLANTIC",
  "VENTNOR",
  "WATER -WORKS",
  "MARVIN -GARDENS",

  "GO TO -JAIL",
  "PACIFIC",
  "NORTH -CAROLINA",
  "COMMUNITY -CHEST",
  "PENNSYL-VANIA",
  "SHORT LINE -R.R.",
  "CHANCE -?",
  "PARK -PLACE",
  "LUXURY -TAX",
  "BOARDWALK";

STRING ARRAY PROPERTY_NAME[0:39];

DEFINE GO=0;
DEFINE INCOME_TAX=4;
DEFINE READING=5;
DEFINE JAIL=10;
DEFINE ST_CHARLES=11;
DEFINE ELECTRIC_CO=12;
DEFINE FREE_PARKING=20;
DEFINE ILLINOIS=24;
DEFINE WATER_WORKS=28;
DEFINE GO_TO_JAIL=30;
DEFINE PARK_PLACE=37;
DEFINE LUXURY_TAX=38;
DEFINE BOARDWALK=39;

PRELOAD_WITH
-1, 0,-2, 0,-1, 0, 0,-3, 0, 0,
-1, 0, 0, 0, 0, 0, 0, 0,-2, 0,
-1, 0,-3, 0, 0, 0, 0, 0, 0, 0,
-1, 0, 0,-2, 0, 0,-3, 0,-1, 0;
  INTEGER ARRAY OWNED[0:39];

PRELOAD_WITH
  30,  60,  90, 100, 150, 180, 200, 220, 250, 300, 330, 360, 390, 450, 500, 600,
  90, 180, 270, 300, 450, 500, 550, 600, 700, 750, 800, 850, 900,1000,1100,1200,
 160, 320, 400, 450, 625, 700, 750, 800, 875, 925, 975,1025,1100,1200,1300,1500,
 250, 450, 550, 600, 750, 900, 950,1000,1050,1100,1150,1200,1275,1400,1500,2000;
  INTEGER ARRAY HOUSES[2:5,0:15];

DEFINE UNOWNED	=  0;
DEFINE SPECIAL	= -1;
DEFINE CHESTSQ	= -2;
DEFINE CHANSQ	= -3;
DEFINE FOOCON	= -3;	α FOOCON IS SMALLEST OF THESE;
α THE CARDS;

DEFINE CARDWIDTH=24;

DEFINE CHANMAX=15;
PRELOAD_WITH
"+BANK PAYS YOU DIVIDEND OF $50",
"+YOUR BUILDING AND LOANEND MATURES, COLLECT $150",
"-PAY POOR TAX OF $15",
"→"&GO&"ADVANCE TO GO, COLLECT $200",
"→"&BOARDWALK&"TALK A WALK ON THE BOARDWALK, ADVANCE TOKEN TO BOARDWALK",
"→"&ILLINOIS&"ADVANCE TO ILLINOIS AVE.",
"→"&ST_CHARLES&"ADVANCE TO ST. CHARLES PLACE, IF YOU PASS GO, COLLECT $200",
"→"&READING&"TALK A RIDE IN THE READING, IF YOU PASS GO, COLLECT $200",
"←GO BACK 3 SPACES!",
"AMAKE GENERAL REPAIRS ON ALL YOUR PROPERY, $25 FOR EACH HOUSE, $100 FOR EACH HOTEL",
"EYOU HAVE BEEN ELECTED CHAIRMAN OF THE BOARD, PAY EACH PLAYER $50",
"GGET OUT OF JAIL FREE",
"NADVANCE TOKEN TO THE NEAREST RAILROAD",
"NADVANCE TOKEN TO THE NEAREST UTILITY",
"JGO TO JAIL, GO DIRECTLY TO JAIL, DO NOT PASS GO, DO NOT COLLECT $200";
  STRING ARRAY CHANCECARDS[0:CHANMAX];

DEFINE CHESTMAX=16;
PRELOAD_WITH
"+BANK ERROR IN YOUR FAVOR, COLLECT $200",
"+YOU HAVE WON SECOND PRIZE IN A BEAUTY CONTEST, COLLECT $10",
"+INCOME TAX REFUND, COLLECT $20",
"+RECIEVE FOR SERVICES, $25",
"+FROM SALE OF STOCK, YOU GET $45",
"+YOU INHERIT $100",
"+XMAS FUND MATURES, COLLECT $100",
"+LIFE INSURANCE MATURES, COLLECT $100",
"-PAY SCHOOL TAX OF $150",
"-PAY HOSPITAL $100",
"-PAY DOCTOR'S FEE, PAY $50",
"→"&GO&"ADVANCE TO GO, COLLECT $200",
"AYOUR ARE ASSESSED FOR STREET REPAIRS, $40 ON EACH HOUSE AND $115 ON EACH HOTEL",
"EGRAND OPERA OPENING, COLLECT $50 FROM EVERY PLAYER",
"GGET OUT OF JAIL FREE",
"NADVANCE TOKEN TO THE NEAREST RAILROAD",
"JGO TO JAIL, GO DIRECTLY TO JAIL, DO NOT PASS GO, DO NOT COLLECT $200";
  STRING ARRAY CHESTCARDS[0:CHESTMAX];

α OPCODES:

+  PLAYER RECIEVES AMOUNT AFTER '$`
-  PLAYER MUST PAY AMOUNT AFTER '$`
→  ADVANCE TO LOCATION, PASSING GO, ETC.
←  GO BACK 3 SPLACES!
A  YOU ARE ASSESSED...
E  EACH PLAYER (IF CHANCE, PAY, IF C.C., COLLECT)
G  GET OF JAIL FREE
N  ADVANCE TO NEAREST...
J  GO TO JAIL...
;

INTEGER ARRAY CHANDECK[0:CHANMAX],CCDECK[0:CHESTMAX];
α MISC. DISPLAY ROUTINES;

PROCEDURE RECTANGLE(INTEGER X,Y,XINC,YINC);
    ⊂ AIVECT(X-XINC/2,Y-YINC/2);
      RVECT(XINC,0);
      RVECT(0,YINC);
      RVECT(-XINC,0);
      RVECT(0,-YINC) ⊃;

INTEGER PROCEDURE PX(INTEGER N);
  RETURN(IF N<20 THEN -1 ELSE 1);

INTEGER PROCEDURE PY(INTEGER N);
  RETURN(IF N<10∨N≥30 THEN -1 ELSE 1);

PROCEDURE SETPOS(INTEGER N,XOFFSET,YOFFSET);
  ⊂ INTEGER T;
    AIVECT(XOFFSET+450*(T←PX(N))+45*(N MOD 10)*(PX((N+10)MOD 40)-T),
      YOFFSET+450*(T←PY(N))+45*(N MOD 10)*(PY((N+10)MOD 40)-T)) ⊃;

BOOLEAN PROCEDURE ANSWERYES;
  ⊂ INTEGER T;
    RETURN((T←INCHWL)="Y"∨T="y") ⊃;

PROCEDURE DPYMSG(STRING S);
  ⊂ DPYSET(DPYBUF);
    AIVECT(-400,-100);
    DPYBIG(3);
    DPYBRT(4);
    DPYSST(S);
    DPYOUT(MSGPOG) ⊃;

PROCEDURE DPYMSG2(STRING S);
  ⊂ DPYSET(DPYBUF);
    AIVECT(-400,-150);
    DPYBIG(2);
    DPYBRT(3);
    DPYSST(S);
    DPYOUT(MSG2POG) ⊃;

PROCEDURE FLASH(INTEGER T; STRING S);
  ⊂ DPYMSG(S); CALL(T,"SLEEP") ⊃;

PROCEDURE FLASH2(INTEGER T; STRING S);
  ⊂ DPYMSG2(S); CALL(T,"SLEEP") ⊃;
α ROLL DICE;

PROCEDURE DPYDICE(INTEGER N,X,Y,WIDTH);
⊂ STRING COMSTR;
  PRELOAD_WITH "5","19","357","1379","13579","123789";
    OWN STRING ARRAY PIPS[1:6];

α  THESE MEAN

   1  2  3

   4  5  6

   7  8  9
;
  COMSTR←PIPS[N];
  RECTANGLE(X,Y,WIDTH,WIDTH);
  WIDTH←WIDTH%4;
  WHILE COMSTR DO
    ⊂ INTEGER T;
      DPYBIG(2);
      AIVECT(X+WIDTH*((T←LOP(COMSTR)-"1")MOD 3-2)+2,Y+WIDTH*(T%3-2)+4);
      DPYSST("O") ⊃ ⊃;

INTEGER PROCEDURE ROLLDICE;
  ⊂ INTEGER T,U;
    DPYSET(DPYBUF);
    DPYDICE(T←6*RANDOM+1,70,0,50);
    DPYDICE(U←6*RANDOM+1,-70,0,50);
    AIVECT(IF (ROLL←T+U)>9 THEN -35 ELSE -10,-20);
    DPYBIG(5);
    DPYSST(CVS(ROLL));
    DPYOUT(DICE);
    DOUBLES←IF T=U THEN 1 ELSE 0;
    RETURN(ROLL) ⊃;
α OWNERSHIP ROUTINES;

STRING PROCEDURE CVP(INTEGER LOC);
  ⊂ STRING S;
    INTEGER I;
    S←PROPERTY_NAME[LOC];
    FOR I←1 STEP 1 UNTIL LENGTH(S) DO
      IF S[I FOR 1]="-" THEN DONE;
    RETURN(IF I≠LENGTH(S) THEN S[1 FOR I-1]&S[I+1 FOR ∞] ELSE S);
    ⊃;

INTEGER PROCEDURE GETDOLLARS(STRING S);
  ⊂  WHILE S∧LOP(S)≠"$" DO;
     IF ¬S THEN USERERR(0,0,"ILLEGAL CARD!");
     RETURN(CVD(S)) ⊃;
	
INTEGER PROCEDURE OWNERSHIP(INTEGER LOC);
  RETURN(OWNED[LOC] LAND '77);

STRING PROCEDURE CVOWN(INTEGER LOC);
  RETURN(INITIALS[OWNERSHIP(LOC)]);
α THE PRICING;

α THIS SECTION IS DECIDATED TO OUR(?) PRESIDENT OF 1969-1972;

INTEGER PROCEDURE COST(INTEGER LOC);
  RETURN(IF LOC MOD 5=0 THEN 200
    ELSE IF LOC<5 THEN 60
    ELSE IF LOC=ELECTRIC_CO∨LOC=WATER_WORKS THEN 150
    ELSE IF LOC=PARK_PLACE THEN 350
    ELSE IF LOC=BOARDWALK THEN 400
    ELSE IF LOC MOD 5=4 THEN 80+40*(LOC%5)
    ELSE 60+40*(LOC%5)
);

INTEGER PROCEDURE S_RENTON(INTEGER LOC);
  IF OWNED[LOC]>'600 THEN RETURN(0)
    ELSE IF LOC MOD 5=0 THEN ⊂ INTEGER I,RAILS;
      RAILS←0;
      FOR I←5 STEP 5 UNTIL 35 DO
	IF OWNED[LOC]=OWNED[I] THEN RAILS←RAILS+50;
      RETURN(RAILS) ⊃
    ELSE IF ¬(OWNED[LOC] LAND '700) THEN
      RETURN(IF LOC=BOARDWALK THEN 50
	ELSE IF LOC=PARK_PLACE THEN 35
	ELSE IF LOC MOD 5=4 THEN 4+4*(LOC%5)
	ELSE 2+4*(LOC%5))
    ELSE IF OWNED[LOC] LAND '700='100 THEN
      RETURN(IF LOC=BOARDWALK THEN 200
	ELSE IF LOC=PARK_PLACE THEN 175
	ELSE IF LOC MOD 5=4 THEN 20+20*(LOC%5)
	ELSE 10+20*(LOC%5))
    ELSE RETURN(HOUSES[OWNED[LOC]%'700
	,IF (LOC LAND '77)MOD 5=4 THEN 1+LOC%5 ELSE LOC%5]);

INTEGER PROCEDURE RENTON(INTEGER LOC);
  IF LOC=WATER_WORKS∨LOC=ELECTRIC_CO THEN
      RETURN(ROLL*(IF OWNED[LOC]>'100 THEN 0
	ELSE IF OWNED[LOC]=OWNED[WATER_WORKS+ELECTRIC_CO-LOC] THEN 10 ELSE 4))
    ELSE IF LOC MOD 5 THEN RETURN(S_RENTON(LOC))
    ELSE ⊂ INTEGER I,M,T; M←2;
      FOR I←(T←5*(LOC%5))+1 STEP 1 UNTIL T+4 DO
        IF OWNED[I]≥0 THEN IF OWNED[I]LAND '77≠OWNED[LOC] THEN M←1;
      RETURN(M*S_RENTON(LOC))⊃;
α DISPLAY STATE;

PROCEDURE UPDATE;
  ⊂ INTEGER I,J,OFFSET;
    DPYSET(DPYBUF);
    FOR I←1 STEP 1 UNTIL PLAYERS DO ⊂
      OFFSET←0;
      FOR J←1 STEP 1 UNTIL I-1 DO
	IF POS[I]=POS[J] THEN OFFSET←OFFSET+1;
      IF INJAIL[J] THEN AIVECT(-405+3,405-93+14*OFFSET)
	ELSE SETPOS(POS[I]MOD 40,-45,-45+14*OFFSET);
      DPYBIG(2);
      DPYBRT(5);
      DPYSST(INITIALS[I]) ⊃;
    AIVECT(0,-200);
    DPYBIG(2);
    DPYBRT(2);
    OFFSET←200;
    FOR I←1 STEP 1 UNTIL PLAYERS DO
      ⊂ AIVECT(150,OFFSET);
        DPYSST(INITIALS[I]);
	AIVECT(300,OFFSET);
	DPYSST("$"&CVS(MONEY[I])&(IF INJAIL[I] THEN "  (IN JAIL)" ELSE ""));
	OFFSET←OFFSET-25 ⊃;
    DPYOUT(ACCOUNT) ⊃;


PROCEDURE DPYOWNERS;
  ⊂ INTEGER I;
    DPYSET(DPYBUF);
    DPYBIG(1);
    DPYBRT(3);
    FOR I←0 STEP 1 UNTIL 39 DO
      IF OWNED[I]>0 THEN
        ⊂ SETPOS(I,-24+35*(PY((I+10)MOD 40)-PY(I)),-5+27*(PX(I)-PX((I+10)MOD 40)));
	  DPYSST(CVOWN(I)&(IF OWNED[I]<'100 THEN ""
	    ELSE "("&(CASE OWNED[I]%'100 OF ("","1","2","3","4","H","M"))&")"))⊃;
    DPYOUT(OWNERS)⊃;

PROCEDURE RESETCARDS;
  ⊂ DPYSET(DPYBUF);
    DPYBIG(3);
    AIVECT(-60,-280);
    DPYSST(" CHANCE ");
    AIVECT(-60,-320);
    DPYSST("   ?    ");
    DPYOUT(CHANCE);
    DPYSET(DPYBUF);
    DPYBIG(3);
    AIVECT(-65,280);
    DPYSST("  CHEST  ");
    AIVECT(-65,320);
    DPYSST("COMMUNITY");
    DPYOUT(COMCHEST) ⊃;
α PLAYER HAS TO SPEND MONEY FOR SOMETHING;

α THIS SECTION IS DEDICATED TO THOSE KIND PEOPLE WHO GAVE US SKYSCRAPERS IN
  PALO ALTO;

α HE WANTS TO (OR HAS TO) MORTGAGE SOMETHING!!;
PROCEDURE MORTGAGE;
  ⊂ INTEGER J,PNUM;
    DO ⊂ STRING S;
	DPYMSG2("WHAT DO YOU WANT TO MORTGAGE?");
	S←INCHWL;
	FOR J←0 STEP 1 UNTIL 39 DO
	  IF OWNED[J]>0∧EQU(S,CVP(J)) THEN
	    IF OWNED[J]LAND '77≠I THEN FLASH2(2,"YOU DON'T OWN "&CVP(J))
	    ELSE IF OWNED[J]>'600 THEN FLASH2(2,CVP(J)&" IS ALREADY MORTGAGED!")
	    ELSE IF OWNED[J]>'100 THEN FLASH2(2,"OOPS, IT SHOULDN'T HAVE HOUSES!")
	    ELSE ⊂ OWNED[J]←OWNED[J]+'600;
		MONEY[I]←MONEY[I]+COST(J)%2;
		DPYMSG2(CVP(J)&" MORTGAGED");
		UPDATE; DPYOWNERS; CALL(2,"SLEEP");
		RETURN ⊃;
	FLASH2(2,"I DON'T BELIEVE I UNDERSTAND YOU FULLY")⊃
 UNTIL FALSE ⊃;

α MAKE HIM GET ENOUGH MONEY;
BOOLEAN PROCEDURE GETFUNDS(INTEGER N);
  DO ⊂ INTEGER T;
    DPYMSG2("C - PAY IN CASH, M - MORTGAGE SOMETHING FIRST, G - GIVE UP");
    IF (T←INCHWL)="C" THEN 
	IF MONEY[I]<N THEN		α GOOD ENOUGH FOR NOW, HE CAN GO INTO DEBT!;
	    DPYMSG2("YOU DON'T HAVE ENOUGH MONEY, YOU'LL HAVE TO MORTGAGE SOMETHING!")
	  ELSE ⊂ DPYMSG2(""); RETURN(TRUE) ⊃
      ELSE IF T="M" THEN MORTGAGE
      ELSE IF T="G" THEN ⊂ FLASH2(1,"YOU GAVE UP"); DPYMSG2(""); RETURN(FALSE)⊃
      ELSE OUTSTR("???") ⊃ UNTIL FALSE;

PROCEDURE COLLECTRENT(INTEGER RENT);
  ⊂ INTEGER FLAG;
    WHILE ¬GETFUNDS(RENT) DO
      ⊂ DPYMSG("IS IT OK WITH YOU, "&CVOWN(POS[I])&", IF HE DOESN'T PAY? ");
	IF ANSWERYES THEN FLAG←TRUE ⊃;
    IF ¬FLAG THEN ⊂ MONEY[I]←MONEY[I]-RENT;
      MONEY[OWNERSHIP(POS[I])]←MONEY[OWNERSHIP(POS[I])]+RENT ⊃;
    UPDATE ⊃;
α SETUP THE BOARD;

	DPYSET(DPYBUF);
	RECTANGLE(0,0,990,990);		α THE BOARDER;
	RECTANGLE(0,0,810,810);
	RECTANGLE(0,-300,200,100);	α THE CARDS;
	RECTANGLE(0,300,200,100);
	AIVECT(-405,405-90);
	RVECT(90,0);
	FOR I←0 STEP 18 UNTIL 90 DO
	  ⊂ RVECT(0,90);
	    RIVECT(-18,-90) ⊃;
	XPOS←-495;
	YPOS←-495;
	XINC←0;
	YINC←90;
	DPYBIG(3);
	FOR I←0 STEP 10 UNTIL 39 DO ⊂
	  FOR J←0 STEP 1 UNTIL 9 DO ⊂ STRING PROP;
	    STRING PROCEDURE CENTER(STRING S);
	      ⊂ WHILE LENGTH(S)<9 DO S←" "&S&" ";
		DPYSST(S);
		⊃;
	    XPOS←XPOS+XINC;
	    YPOS←YPOS+YINC;
	    AIVECT(XPOS,YPOS);
	    RVECT(YINC,-XINC);
	    RIVECT(-(XINC+YINC)/2-45,(XINC-YINC)/2+20);
	    PROP←PROPERTY_NAME[I+J];
	    FOR K←1 STEP 1 UNTIL LENGTH(PROP) DO
	      IF PROP[K FOR 1]="-" THEN DONE;
	    IF I∨J 
	      THEN CENTER(PROP[1 FOR (IF PROP[K-1 FOR 1]=" " THEN K-1 ELSE K)])
	      ELSE DPYSST(" GO! ");
	    DPYBIG(1);
	    IF K≠LENGTH(PROP) THEN ⊂
	      AIVECT(XPOS+YINC-(XINC+YINC)/2-45,YPOS-(XINC+YINC)/2);
	      CENTER(PROP[K+1 FOR ∞]) ⊃ ⊃;
	  XPOS←XPOS+XINC;
	  YPOS←YPOS+YINC;
	  J←YINC;
	  YINC←-XINC;
	  XINC←J ⊃;
α ACTUAL PLAYING;
	PTOCHW(0,'14000+"W");
	FOR I←0 STEP 1 UNTIL CALL(0,"TIMER")LAND '77 DO RANDOM;
	DO ⊂ OUTSTR("
A.I. MONOPOLY

Numbers of players: ");
	  PLAYERS←CVD(INCHWL);
	  ⊃ UNTIL PLAYERS>0∧PLAYERS≤5;
	FOR I←0 STEP 1 UNTIL 39 DO
	  IF OWNED[I]>0 THEN OWNED[I]←0;
	FOR I←1 STEP 1 UNTIL PLAYERS DO ⊂
	  INJAIL[I]←POS[I]←0;
	  MONEY[I]←1500;
	  OUTSTR("Play #"&CVS(I)&"'s Initials: ");
	  INITIALS[I]←INCHWL ⊃;
	TYPLOC(-512,-512);
	DPYOUT(BOARD);
	RESETCARDS;
	I←1+RANDOM*PLAYERS;
	DO ⊂ UPDATE;				α MAKE SURE IT GOT UPDATED;
	  DPYSET(DPYBUF);
	  DPYBIG(6);
	  DPYBRT(6);
	  AIVECT(-200,200);			α INDICATE WHOSE TURN;
	  DPYSST(INITIALS[I]&"'S TURN");
	  DPYOUT(PLAYER);
	  DPYMSG("");				α FLUSH OLD JUNK;
	  DOUBLECOUNT←0;
	  DOUBLES←0;				α JUST IN CASE THING GOT MESSED UP;
	  IF INJAIL[I] THEN INJAIL[I]←INJAIL[I]+1;
	  DO ⊂ BOOLEAN FOOFLAG;
	      FOOFLAG←FALSE;			α SO THAT ADVANCE TOKEN TO NEAREST;
						α AND PAY... DOESN'T CHARGE TWICE!;
	      IF INJAIL[I]>3 THEN ⊂ 		α HE HAS BEEN THERE 3 TURNS;
		DPYMSG("YOU HAVE SERVED YOUR TIME, YOU MAY GO NOW.");
		INJAIL[I]←0;
		UPDATE ⊃;
	      IF INJAIL[I]∧MONEY[I]≥50 THEN ⊂	α GIVE HIM A CHANCE TO BAIL OUT;
		DPYMSG("DO YOU WANT TO PAY $50 TO GET OUT?");
		IF ANSWERYES THEN
		  IF GETFUNDS(50)
		    THEN ⊂ MONEY[I]←MONEY[I]-50; INJAIL[I]←0; UPDATE ⊃;
		DPYMSG("") ⊃;
	      IF DOUBLES			α DID HE THROW DOUBLES LAST TIME?;
		THEN DPYMSG(INITIALS[I]&":  DOUBLES, ROLL AGAIN!");
	      DO ⊂ DPYMSG2("E - EXIT, R - ROLL, U - UNMORTGAGE,");
		IF (TMPSTR←INCHWL)="E" THEN ⊂ DPYMSG("DO YOU REALLY WANT TO EXIT? ");
		    IF ANSWERYES THEN CALL(1,"EXIT") ⊃
		  ELSE IF TMPSTR="U" THEN ⊂	α UNMORTGAGE SOMETHING!;
		    INTEGER J,T;
		    DPYMSG("WHICH PROPERTY?");
		    TMPSTR←INCHWL;  
		    FOR J←39 STEP -1 UNTIL 0 DO		α SEARCH FOR IT;
		      IF EQU(TMPSTR,CVP(J)) THEN DONE;
		    IF OWNED[J]='600+I THEN ⊂ DPYMSG("YOU NEED $"
			  &CVS(T←COST(J)%2+COST(J)%40)&" TO UNMORTGAGE IT.");
			IF GETFUNDS(T) THEN ⊂ MONEY[I]←MONEY[I]-T;
			    OWNED[J]←OWNED[J]LAND '77;
			    UPDATE;
			    DPYOWNERS;
			    FLASH(2,CVP(J)&" UNMORTGAGED.") ⊃
			  ELSE FLASH(1,"OH, WELL")⊃
		      ELSE IF OWNED[J]LAND '77=I THEN FLASH(2,"THAT ISN'T MORTGAGED!")
		      ELSE IF OWNED[J]=0 THEN FLASH(2,"YOU CAN'T, IT'S UNOWNED")
		      ELSE IF OWNED[J]<0 THEN
			FLASH(2,"I DON'T THINK I UNDERSTAND YOU FULLY")
		      ELSE FLASH(2,"SOMEONE ELSE OWNS THAT!") ⊃;
	        RESETCARDS ⊃			α FLUSH OLD CARDS;
		UNTIL TMPSTR="R";		α UNTIL HE'S READY TO ROLL;
	      TEMP←ROLLDICE;
	      IF ¬INJAIL[I]∨DOUBLES THEN	α MOVE SLOW ENOUGH TO MAYBE SEE IT;
		WHILE TEMP DO
		  ⊂ POS[I]←POS[I]+1; TEMP←TEMP-1; CALL(0,"SLEEP"); UPDATE ⊃;
	      IF DOUBLES THEN DOUBLECOUNT←DOUBLECOUNT+1;  α CHECK FOR TOO MANY DOUBLES;
	      IF POS[I]=GO_TO_JAIL∨DOUBLECOUNT>2 THEN ⊂
		DPYMSG((IF DOUBLECOUNT>2 THEN "TOO MANY DOUBLES, " ELSE "")
		  &"YOU GET TO GO TO JAIL!	");
		CALL(3,"SLEEP");		α SO HE CAN SEE HOW HE GOT THERE;
		POS[I]←JAIL;		
		INJAIL[I]←1;
		DOUBLES←0;
		DONE ⊃;
	      IF POS[I]≥40 THEN ⊂ MONEY[I]←MONEY[I]+200;	α PASSING GO;
		  POS[I]←POS[I] MOD 40; UPDATE;
		  FLASH(2,"YOU PASSED GO, COLLECT $200") ⊃;
	      IF OWNED[POS[I]]=-2∨OWNED[POS[I]]=-3 THEN		α THE CARDS;
		⊂ α WE HAVE FOUND A CHANCE OR COMMUNITY CHEST CARD!;
		  INTEGER TYPE;
		  STRING CARD;
		  PROCEDURE CENTER(STRING C);
		    ⊂ INTEGER POS,I;		α WE MAKE TEXT FIX WITH IN A BOX;
		      POS←30;
		      C←IF C="→"∨C="N" THEN C[3 FOR ∞]
			ELSE C[2 FOR ∞];
		      DO ⊂ AIVECT(-100,TYPE*300+POS);	α SET POSITION IN BOX;
			POS←POS-18;
			I←CARDWIDTH+1;
			IF LENGTH(C)>CARDWIDTH THEN 	α LOOK FOR A BREAK IN LINE;
			  WHILE I∧C[I FOR 1]≠" " DO  I←I-1;
			IF I THEN DPYSST(C[1 FOR I-1]) ELSE USERERR(0,0,"BAD CARD");
							α DISPLAY THIS LINE;
			C←C[I+1 FOR ∞] ⊃ UNTIL ¬C ⊃;	α SET TO REST OF TEXT;
		  TYPE←IF OWNED[POS[I]]=-2 THEN 1 ELSE -1;
		  DPYSET(DPYBUF);			α SET UP FOR DISPLAY;
		  DPYBIG(1);
		  DPYBRT(4);
		  IF TYPE=1 THEN			α KIND OF CARD;
		    ⊂ CENTER(CARD←CHESTCARDS[CHESTMAX*RANDOM]);
							α NOT REALLY A DECK YET!;
		      DPYOUT(COMCHEST) ⊃		α DISPLAY IT;
		    ELSE ⊂ CENTER(CARD←CHANCECARDS[CHANMAX*RANDOM]);
		      DPYOUT(CHANCE) ⊃;
							α NOW TAKE ACTION!;
		  IF CARD="+" THEN MONEY[I]←MONEY[I]+GETDOLLARS(CARD)
							α HE RECIEVES;
		    ELSE IF CARD="-" THEN ⊂ INTEGER T;
			WHILE ¬GETFUNDS(T←GETDOLLARS(CARD)) DO
			  DPYMSG("YOU MUST PAY $"&CVS(T));
			MONEY[I]←MONEY[I]-T; UPDATE ⊃ 	α HE PAYS;
		    ELSE IF CARD="←" THEN ⊂ POS[I]←POS[I]-3; UPDATE ⊃
							α GO BACK 3 SPACES!;
		    ELSE IF CARD="→" THEN ⊂ 		α ADVANCE TO...;
		      IF CARD[2 FOR 1]<POS[I] THEN MONEY[I]←MONEY[I]+200;
					α IF YOU PASS GO, COLLECT $200;
		      POS[I]←CARD[2 FOR 1] ⊃
		    ELSE IF CARD="J" THEN ⊂ POS[I]←JAIL; α GO TO JAIL...;
		      INJAIL[I]←1; FLASH(2,"YOU GET TO GO TO JAIL") ⊃
		    ELSE IF CARD="N" THEN	α ADVANCE TOKEN TO NEAREST...;
		      IF CARD[2 FOR 1]="R" THEN
			⊂ WHILE (POS[I]←(POS[I]+1)MOD 40)MOD 10≠5 DO ⊂ UPDATE;
			    IF ¬POS[I] THEN MONEY[I]←MONEY[I]+200; UPDATE ⊃;
						α ADVANCE TO NEAREST;
			  IF OWNED[POS[I]]>0∧OWNED[POS[I]]LAND '77≠I∧
			      OWNED[POS[I]]<'100 THEN	α IF OWNED R.R. ...;
			    ⊂ DPYMSG("YOU OWE "&CVOWN(POS[I])&" 
				"&2*RENTON(POS[I]));
			      COLLECTRENT(2*RENTON(POS[I]));
			      FOOFLAG←TRUE ⊃ ⊃
			ELSE ⊂ WHILE (POS[I]←(POS[I]+1)MOD 40)=ELECTRIC_CO
			     ∨POS[I]=WATER_WORKS DO	α OWNED UTILITY;
				⊂ UPDATE;		α ADVANCE TO IT;
				  IF ¬POS[I] THEN MONEY[I]←MONEY[I]+200 ⊃;
			  IF OWNED[POS[I]]>0∧OWNED[POS[I]]LAND '77≠I∧
			      OWNED[POS[I]]<'100 THEN
			    ⊂ DPYMSG("YOU OWE "&CVOWN(POS[I])&" 
				"&10*ROLLDICE);
			      COLLECTRENT(10*ROLL);
			      FOOFLAG←TRUE ⊃ ⊃
		    ELSE ⊂ DPYMSG(
"I DON'T KNOW WHAT TO DO WITH THIS, PLEASE TYPE <RETURN>");
			   INCHWL ⊃;
		  UPDATE ⊃;
	      IF INJAIL[I] THEN IF INJAIL[I]=1 THEN ELSE OUTSTR("(IN JAIL)")
		ELSE IF OWNED[POS[I]]≤0 THEN CASE OWNED[POS[I]]-CHANSQ OF BEGIN
	[UNOWNED-FOOCON] ⊂ DPYMSG(CVP(POS[I])&"($"&CVS(COST(POS[I]))
		    &") IS UNOWNED, DO YOU WISH TO BUY IT?");
		  IF ANSWERYES
		    THEN IF GETFUNDS(COST(POS[I]))
		      THEN ⊂ MONEY[I]←MONEY[I]-COST(POS[I]);
			OWNED[POS[I]]←I;
			UPDATE;
			DPYOWNERS;
			DPYMSG(CVP(POS[I])&" PURCHASED.");
			CALL(2,"SLEEP") ⊃ ⊃;			
	[SPECIAL-FOOCON] CASE POS[I] OF ⊂
	  [JAIL]	⊂ DPYMSG("JUST VISITING"); CALL(2,"SLEEP") ⊃;
	  [INCOME_TAX] ⊂  DPYMSG("INCOME TAX!  10% OR $200");
			  WHILE TRUE DO ⊂ INTEGER T;
			    IF (T←INCHWL)="$"∧T="2"
			      THEN IF GETFUNDS(200) THEN ⊂ MONEY[I]←MONEY[I]-200;
				  DONE ⊃
				ELSE DPYMSG("YOU MUST PAY INCOME TAX!, 10% OR $200")
			      ELSE IF T="%"∨T="1"
				THEN ⊂ MONEY[I]←MONEY[I]-MONEY[I]/10; DONE ⊃
			      ELSE OUTSTR("???") ⊃ ⊃;
	  [LUXURY_TAX] ⊂  DPYMSG("YOU GET TO PAY LUXURY TAX OF $75.");
			  WHILE ¬GETFUNDS(75)
			    DO DPYMSG("YOU MUST PAY LUXURY TAX OF $75");
			  MONEY[I]←MONEY[I]-75 ⊃;	α WHAT IF MONEY<75!;
	  [BOARDWALK] NO_OP;			α STOP CASE OVERFLOW!;
	  [FREE_PARKING]  FLASH(2,"FREE PARKING!") ⊃ ⊃  α LAST ITEM ALWAYS!;
		ELSE IF OWNED[POS[I]]LAND '77=I THEN
		  FLASH(2,"YOU OWN THIS PROPERTY")
		ELSE IF OWNED[POS[I]]>'600 THEN DPYMSG(CVP(POS[I])
		  &" IS MORTGAGED BY "&CVOWN(POS[I]))
		ELSE IF ¬FOOFLAG THEN ⊂ LABEL FIN; BOOLEAN FLAG;
		  FLAG←FALSE;
		  DPYMSG("YOU OWE "&CVOWN(POS[I])&" $"&CVS(RENTON(POS[I])));
	 	  COLLECTRENT(RENTON(POS[I])) ⊃;
	    UPDATE ⊃ UNTIL ¬DOUBLES;
	  I←(1+I MOD PLAYERS) ⊃ UNTIL FALSE;
	OUTSTR("SOMEHOW WE EXITED FROM THE MAIN LOOP!");
END "MONPLY";